<?php
    /**
     * Shop.php
     *
     * Niushop商城系统 - 团队十年电商经验汇集巨献!
     * =========================================================
     * Copy right 2015-2025 山西牛酷信息科技有限公司, 保留所有权利。
     * ----------------------------------------------
     * 官方网址: http://www.niushop.com.cn
     * 这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用。
     * 任何企业和个人不允许对程序代码以任何形式任何目的再发布。
     * =========================================================
     * @author : niuteam
     * @date : 2015.1.17
     * @version : v1.0.0.0
     */

    namespace data\service;

    /**
     * 交互服务层
     */

    use data\service\BaseService as BaseService;
    use data\api\IPushMessage;
    use data\model\SysWechatLogModel;
    use data\extend\WchatOauth;
    use data\model\TzOrderModel;
    use think\Config;
    use think\Log;
    use data\service\promotion\PromoteRewardRule;

    class PushMessage extends BaseService implements IPushMessage
    {
        /**
         * 生成日志
         * @param $data
         * @return bool
         */
        public function addMessageLog($data)
        {
            $sysWechatLog = new SysWechatLogModel();
            return $sysWechatLog->save($data);
        }

        public function getMessageLog($type)
        {
            $sysWechatLog = new SysWechatLogModel();
            return $sysWechatLog->where(['type' => $type])->order('id DESC')->find()->toArray();
        }

        /**
         * 发送模板消息
         */
        public function templateMessageSend($openid, $templateId, $data, $uri = '')
        {
            $wchat  = new WchatOauth();
            $array  = array(
                'touser'      => $openid,
                'template_id' => $templateId,
                'url'         => $uri,
                'topcolor'    => '#FF0000',
                'data'        => $data,
            );
            $json   = json_encode($array);
            $url    = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
            $res    = $wchat->pushMessageSend($url, $json);
            $resarr = json_decode($res, true);
            $this->createResponseStatus($url, 'post/json', $json, $resarr['errcode'], $resarr['errmsg'], $res);
            return $resarr;
        }

        public function saveTzOrder($data)
        {
            $status   = 0;
            $now_time = time();
            $tzOrder  = new TzOrderModel();
            $arr      = [
                'openid'      => $data['open_id'],     // 用户微信openid
                'order_id'    => $data['order_id'],     // 用户订单id
                'shop_name'   => $data['store_name'],     // 订单消费的商户名称
                'shop_id'     => $data['store_id'],     // 订单消费的商户ID
                'amount'      => $data['amount'],     // 消费金额
                'time'        => $data['time'],     // 订单交易时间
                'create_time' => $now_time,     // 创建时间
                'status'      => $status,
            ];
            // 先将数据入库保存
            $re = $tzOrder->save($arr);
            if ($re) {
                $res = $this->executeSendTemp();
                if ($res == 3) {
                    return false;
                }
                return true;

                /*// 保存成功后判断是否关注过
                $create_order_time = strtotime($data['time']);
                $user              = new User();
                $userInfo          = $user->getUserInfoData($data['open_id']);
                if (!empty($userInfo) && $userInfo['user_status'] > 0) {
                    // 关注过的则判断后台设置是否启用下单送积分
                    $promote_reward_rule = new PromoteRewardRule();
                    // 平台赠送积分
                    $jf = $promote_reward_rule->XdMemberSendPoint(0, $userInfo['uid']);
                    if ($jf['res'] > 0) {
                        if ($create_order_time + 180 < $now_time) {
                            $tzOrder->isUpdate()->save(['status' => 3, 'update_time' => $now_time], ['id' => $tzOrder->id]);
                            return true;
                        }
                        $data['add_points']     = '+' . $jf['xz'];
                        $data['surplus_points'] = $jf['sy'];
                        $data['nickname']       = $userInfo['nick_name'];
                        $data['username']       = $userInfo['user_name'];
                        // 积分增加成功发送模板
                        $res = $this->sendTemp($data);
                        if ($res) {
                            $status = 2;
                        } else {
                            $status = 1;
                        }
                        $tzOrder->data(['id' => $data['id'], 'status' => $status, 'add_points' => $jf['xz'], 'surplus_points' => $jf['sy'], 'update_time' => $now_time], true)->isUpdate(true)->save();
                    }
                }
                return true;*/
            }
            return false;
        }

        public function sendTemp($data)
        {
            // 读取模板
            $template_key = $data['type'] ? : '';
            $template     = Config::get('wechatTemplate.' . $template_key);
            $uri          = $data['uri'] ? : $template['url'];
            $open_id      = $data['open_id'] ? : '';
            // $param        = true;
            foreach ($template['template'] as $key => $vo) {
                // 遍历配置的模板，使用正则匹配替换模板中的变量
                $string                              = $vo['value'];
                $string                              = preg_replace_callback(
                    '/\{\{(([a-z_]+)|([a-z_]+\|.*?))\}\}/',
                    function($mat) use ($data) {
                        preg_match('/[^\{\{\}\}]+/', $mat[0], $matches);
                        $offset = strpos($matches[0], '|');
                        if ($offset) {
                            $variate = substr($matches[0], 0, $offset);
                            $default = substr($matches[0], $offset + 1);
                            $repStr  = $data[$variate] ? : $default;
                        } else {
                            $repStr = $data[$matches[0]] ? : '';
                        }

                        return $repStr;
                    },
                    $string
                );
                $template['template'][$key]['value'] = $string;
            }

            $res = $this->templateMessageSend($open_id, $template['id'], $template['template'], $uri);
            if ($res['errcode'] == 0 && $res['errmsg'] == 'ok') {
                return true;
            }
            return false;
        }

        /**
         * 生成响应日志
         * @return bool
         */
        public function createResponseStatus($url, $method, $request_body, $error_code, $error_msg, $response, $source = 'WX')
        {
            $data = [
                'url'            => $url,
                'method'         => $method,
                'type'           => 2,
                'request_header' => '',
                'request_body'   => $request_body,
                'error_code'     => $error_code,
                'error_msg'      => $error_msg,
                'response'       => $response,
                'source'         => $source,
                'create_time'    => time(),
            ];
            $this->addMessageLog($data);
            return true;
        }

        /**
         * 计划任务执行发送模板消息
         * @return bool
         * @throws \think\db\exception\DataNotFoundException
         * @throws \think\db\exception\ModelNotFoundException
         * @throws \think\exception\DbException
         */
        public function executeSendTemp()
        {
            try {
                // is_file('tzOrderLock.lock') && unlink('tzOrderLock.lock');
                // 先将数据取出设置文件锁，防止重复执行
                if (is_file('tzOrderLock.lock') && file_get_contents('tzOrderLock.lock') == 'lock') {
                    return 2;
                }
                file_put_contents('tzOrderLock.lock', 'lock');
                // sleep(10);

                $now_time            = time();
                $tzOrder             = new TzOrderModel();
                $promote_reward_rule = new PromoteRewardRule();
                $user                = new User();
                $arr                 = $tzOrder->where(['status' => ['not in', [2,3,4]]])->select();


                $arr                 = collection($arr)->toArray();
                if (empty($arr)) {
                    unlink('tzOrderLock.lock');
                    return 1;
                }

                foreach ($arr as $key => $data) {
                    $data['open_id'] = $data['openid'];
                    unset($data['openid']);
                    // 判断是否超时
                    $create_order_time = strtotime($data['time']);
                    if ($create_order_time + 180 < $now_time) {
                        // 状态为1 情况下 超出时效 状态改为4
                        if ($data['status'] == 1) {
                            $tzOrder->data(['id' => $data['id'], 'status' => 4, 'update_time' => $now_time], true)->isUpdate(true)->save();
                            continue;
                        }
                        $tzOrder->data(['id' => $data['id'], 'status' => 3, 'update_time' => $now_time], true)->isUpdate(true)->save();

                        continue;
                    }
                    // 判断是否关注过 并成功注册
                    $userInfo = $user->getUserInfoData($data['open_id']);
                    if (!empty($userInfo) && $userInfo['user_status'] > 0) {
                        $data['nickname'] = $userInfo['nick_name'];
                        $data['username'] = $userInfo['user_name'];
                        $data['type']     = 'order';
                        if ($data['status'] == 0) {
                            // 平台赠送积分
                            $jf = $promote_reward_rule->XdMemberSendPoint(0, $userInfo['uid']);
                            if ($jf['res'] > 0) {
                                $data['add_points']     = '+' . $jf['xz'];
                                $data['surplus_points'] = $jf['sy'];

                                // print_r($data);
                                // 积分增加成功发送模板
                                $res = $this->sendTemp($data);
                                if ($res) {
                                    $status = 2;
                                } else {
                                    $status = 1;
                                }
                                $tzOrder->data(['id' => $data['id'], 'status' => $status, 'add_points' => $jf['xz'], 'surplus_points' => $jf['sy'], 'update_time' => $now_time], true)->isUpdate(true)->save();
                            }
                        } elseif ($data['status'] == 1) {
                            // 重发模板消息
                            $data['add_points'] = '+' . $data['add_points'];
                            $res                = $this->sendTemp($data);
                            if ($res) {
                                $status = 2;
                            } else {
                                $status = 1;
                            }
                            $tzOrder->data(['id' => $data['id'], 'status' => $status, 'update_time' => $now_time], true)->isUpdate(true)->save();
                        }
                    }
                    continue;
                }
                unlink('tzOrderLock.lock');
                return 1;
            } catch (\Exception $e) {
                Log::write('tzOrder 执行 ID 为 ' . $data['id'] . '的数据出错，报错信息如下：' . $e->getMessage(), 'order');
                $url = 'https://gzh.tiaze.com/index.php?s=/wap/transfer/executesendtemp';
                $this->createResponseStatus($url, 'GET', $data, $e->getCode(), $e->getMessage(), '', 'JHRW');
                dingding('计划任务执行出错', $e->getCode(), $e->getMessage(), request()->url(), $data, $e->getFile(), $e->getLine());
                unlink('tzOrderLock.lock');
                return 3;
            }
        }


        /**
         * getOrederlist 获取天择订单分页数据
         * @param int $page_index
         * @param int $page_size
         * @param string $condition
         * @param string $order
         * @return array
         */
        public function getOrderList($page_index = 1, $page_size = 0, $condition = '', $order = '')
        {
            $tzOrder    = new TzOrderModel();
            $order_list = $tzOrder->pageQuery($page_index, $page_size, $condition, $order, '*');
            return $order_list;
        }

        /**
         * getTzOrderCount 天择酒店订单统计
         * @param $starttime
         * @param $endtime
         * @return false|\PDOStatement|string|\think\Collection
         * @throws \think\db\exception\DataNotFoundException
         * @throws \think\db\exception\ModelNotFoundException
         * @throws \think\exception\DbException
         */
        public function getTzOrderCount($starttime,$endtime){
            $tzorder = new TzOrderModel();
            /*$sql    = "select FROM_UNIXTIME(subscribe_date,'%Y-%m-%d')as date,COUNT(*)
FROM sys_weixin_fans
where is_subscribe = 1 and subscribe_date > 1535558400 AND subscribe_date < 1536163200
GROUP BY FROM_UNIXTIME(subscribe_date,'%Y-%m-%d')";*/
            $res = $tzorder->db()->field("DATE_FORMAT(time,'%Y-%m-%d')as date,COUNT(*) as count,sum(add_points) as add_points,sum(amount) as amount")
                ->where([
                    'time' => [['>', $starttime],['<', $endtime]]
                ])
                ->group("DATE_FORMAT(time,'%Y-%m-%d')")
                // ->fetchSql()
                ->order("time ASC")
                ->select();
            return $res;
        }
    }
